<template>
  <div id="printer-container"></div>
</template>

<script>
// import html2Canvas from 'html2canvas'
import jsPDF from 'jspdf'
import FileSaver from 'file-saver'
import html2canvas from 'html2canvas'
import { isStyle } from '@/components/drawStyle.js'

export default {
  data () {
    return {
      iMap: null,
      dims: { // 纸张类型尺寸
        a0: [1189, 841],
        a1: [841, 594],
        a2: [594, 420],
        a3: [420, 297],
        a4: [297, 210],
        a5: [210, 148]
      },
      resolution: { // 分辨率
        '72dpi': 72,
        '150dpi': 150,
        '300dpi': 300
      },
      doing: false // 正在转换数据
    }
  },
  watch: {
    // watch
  },
  mounted () {
    // mounted
  },
  methods: {
    /* Method: print2PDF地图打印到PDF
    * 地图的事件处理绑定
    * 参数：format纸张类型(a0~a5), Resolution分辨率(72,150,300)
    */
    print2PDF (Format, Resolution) {
      this.doing = true // 开始转化地图
      document.body.style.cursor = 'progress' // 修改鼠标样式
      //
      const format = Format
      const resolution = Resolution
      const dim = this.dims[format]
      const width = Math.round(dim[0] * resolution / 25.4) // 宽有多少分辨率点
      const height = Math.round(dim[1] * resolution / 25.4)
      const size = this.$parent.imap.getSize() // DOM中地图的大小（以像素为单位）
      const viewResolution = this.$parent.imap.getView().getResolution() // 获取视图分辨率

      this.$parent.imap.once('rendercomplete', () => {
        const mapCanvas = document.createElement('canvas')
        mapCanvas.width = width
        mapCanvas.height = height
        const mapContext = mapCanvas.getContext('2d')
        Array.prototype.forEach.call(document.querySelectorAll('.ol-layer canvas'), (canvas) => {
          if (canvas.width > 0) {
            const opacity = canvas.parentNode.style.opacity
            mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity)
            const transform = canvas.style.transform
            // Get the transform parameters from the style's transform matrix
            const matrix = transform.match(/^matrix\(([^\(]*)\)$/)[1].split(',').map(Number)
            // 应用变换参数到当期的绘制上下文
            CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix)
            mapContext.drawImage(canvas, 0, 0)
          }
        })
        var pdf = new jsPDF('landscape', undefined, format)
        pdf.addImage(mapCanvas.toDataURL('image/jpeg'), 'JPEG', 0, 0, dim[0], dim[1])
        pdf.save('map.pdf')
        // Reset original map size
        this.$parent.imap.setSize(size)
        this.$parent.imap.getView().setResolution(viewResolution)
        this.doing = false
        document.body.style.cursor = 'auto'
      })
      // Set print size
      const printSize = [width, height]
      this.$parent.imap.setSize(printSize)
      const scaling = Math.min(width / size[0], height / size[1])
      this.$parent.imap.getView().setResolution(viewResolution / scaling)
    },

    getPNG_old (Format, Resolution) {
      this.doing = true // 开始转化地图
      document.body.style.cursor = 'progress' // 修改鼠标样式
      //
      const format = Format
      const resolution = Resolution
      const dim = this.dims[format]
      const width = Math.round(dim[0] * resolution / 25.4) // 宽有多少分辨率点
      const height = Math.round(dim[1] * resolution / 25.4)
      const size = this.$parent.imap.getSize() // DOM中地图的大小（以像素为单位）
      const viewResolution = this.$parent.imap.getView().getResolution() // 获取视图分辨率

      this.$parent.imap.once('rendercomplete', () => {
        const mapCanvas = document.createElement('canvas')
        mapCanvas.width = width
        mapCanvas.height = height
        const mapContext = mapCanvas.getContext('2d')
        Array.prototype.forEach.call(document.querySelectorAll('.ol-layer canvas'), (canvas) => {
          if (canvas.width > 0) {
            const opacity = canvas.parentNode.style.opacity
            mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity)
            const transform = canvas.style.transform
            // Get the transform parameters from the style's transform matrix
            const matrix = transform.match(/^matrix\(([^\(]*)\)$/)[1].split(',').map(Number)
            // 应用变换参数到当期的绘制上下文
            CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix)
            mapContext.drawImage(canvas, 0, 0)
          }
        })
        // 生成图片
        const imgData = mapCanvas.toDataURL('image/png', 1) // , 'PNG', 0, 0, dim[0], dim[1] // mapCanvas.toDataURL(type, 1)
        // this.getFile('plot.png', imgData)
        return imgData
      })
      // Set print size
      const printSize = [width, height]
      this.$parent.imap.setSize(printSize)
      const scaling = Math.min(width / size[0], height / size[1])
      this.$parent.imap.getView().setResolution(viewResolution / scaling)
    },

    /**
     * @description 获取地图图片
     * @param Format {String} 纸张尺寸，如:a0 a1...b5，
     * @param Resolution {Number} 分辨率
     * @param OPT {Object} 参数对象
     * @return null
     */
    getPNG (Format, Resolution, OPT) {
      this.doing = true // 开始转化地图
      document.body.style.cursor = 'progress' // 修改鼠标样式
      //
      // 关闭plot的panel；保持打印页面清洁！-0601
      this.$parent.showPlotPanel(false)
      const format = Format
      const resolution = Resolution
      const dim = this.dims[format]
      const width = Math.round(dim[0] * resolution / 25.4) // 宽有多少分辨率点
      const height = Math.round(dim[1] * resolution / 25.4)
      const size = this.$parent.imap.getSize() // DOM中地图的大小（以像素为单位）
      const viewResolution = this.$parent.imap.getView().getResolution() // 获取视图分辨率

      this.$parent.imap.once('rendercomplete', () => {
        // this.$parent.zoomTxt()
        const mapCanvas = document.createElement('canvas')
        mapCanvas.width = width + 200 // 添加留白左右各50
        mapCanvas.height = height + 300 // 添加留白上下各50
        const mapContext = mapCanvas.getContext('2d')
        Array.prototype.forEach.call(document.querySelectorAll('.ol-layer canvas'), (canvas) => {
          if (canvas.width > 0) {
            const opacity = canvas.parentNode.style.opacity
            mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity)
            const transform = canvas.style.transform
            // Get the transform parameters from the style's transform matrix
            const matrix = transform.match(/^matrix\(([^\(]*)\)$/)[1].split(',').map(Number)
            // 应用变换参数到当期的绘制上下文
            CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix)
            // 在canvas绘制前填充白色背景（new）
            // mapContext.fillStyle = '#fff'
            // mapContext.fillRect(0, 0, mapCanvas.width, mapCanvas.height)
            // new end
            mapContext.drawImage(canvas, 100, 200, width, height)
            // 光标复原
            document.body.style.cursor = 'auto'
          }
        })
        // const imgData = mapCanvas.toDataURL('image/png', 1) // , 'PNG', 0, 0, dim[0], dim[1] // mapCanvas.toDataURL(type, 1)
        // console.log(imgData)
        // this.getFile('plot.png', imgData)
        isStyle(mapContext, OPT, width, height).then(() => {
          // 生成图片
          const imgData = mapCanvas.toDataURL('image/png', 1) // , 'PNG', 0, 0, dim[0], dim[1] // mapCanvas.toDataURL(type, 1)
          console.log(imgData)
          this.getFile('plot.png', imgData)
        })
        // return imgData
        // 回复plot的panel；控制plot操作可见！-0601
        this.$parent.showPlotPanel(true)
      })
      // Set print size
      const printSize = [width, height]
      this.$parent.imap.setSize(printSize)
      const scaling = Math.min(width / size[0], height / size[1])
      this.$parent.imap.getView().setResolution(viewResolution / scaling)
      // 同步渲染
      this.$parent.imap.renderSync()
      this.$parent.zoomTxt()
    },

    /* Method: print2PNG地图打印到PNG
    * 地图的事件处理绑定Format, Resolution
    * 参数：format纸张类型(a0~a5), Resolution分辨率(72,150,300)
    */
    print2PNG () {
      this.doing = true // 开始转化地图
      document.body.style.cursor = 'progress' // 修改鼠标样式
      //
      // let format = Format
      // let resolution = Resolution
      // let dim = this.dims[format]
      // let width = Math.round(dim[0] * resolution / 25.4)  // 宽有多少分辨率点
      // let height = Math.round(dim[1] * resolution / 25.4)
      // let size = this.$parent.imap.getSize()  // DOM中地图的大小（以像素为单位）
      // let viewResolution = this.$parent.imap.getView().getResolution()  // 获取视图分辨率

      this.$parent.imap.once('rendercomplete', () => {
        const mapCanvas = document.createElement('canvas')
        const size = this.$parent.imap.getSize()
        mapCanvas.width = size[0]
        mapCanvas.height = size[1]
        const mapContext = mapCanvas.getContext('2d')
        Array.prototype.forEach.call(document.querySelectorAll('.ol-layer canvas'), (canvas) => {
          if (canvas.width > 0) {
            const opacity = canvas.parentNode.style.opacity
            mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity)
            const transform = canvas.style.transform
            // Get the transform parameters from the style's transform matrix
            const matrix = transform.match(/^matrix\(([^\(]*)\)$/)[1].split(',').map(Number)
            // 应用变换参数到当期的绘制上下文
            CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix)
            mapContext.drawImage(canvas, 0, 0)
          }
        })
        if (navigator.msSaveBlob) {
          // link download attribuute does not work on MS browsers
          navigator.msSaveBlob(mapCanvas.msToBlob(), 'map.png')
        } else {
          // var link = document.getElementById('image-download');
          // link.href = mapCanvas.toDataURL();
          // link.click();
          mapCanvas.toBlob((blob) => {
            FileSaver.saveAs(blob, 'map.jpg')
          }, 'image/jpeg', 0.95)
        }
        // 关闭状态信息
        this.doing = false
        document.body.style.cursor = 'auto'
      })
      this.$parent.imap.renderSync()
    },

    // 获取像素密度
    getPixelRatio (context) {
      var backingStore = context.backingStorePixelRatio ||
        context.webkitBackingStorePixelRatio ||
        context.mozBackingStorePixelRatio ||
        context.msBackingStorePixelRatio ||
        context.oBackingStorePixelRatio ||
        context.backingStorePixelRatio || 1
      return (window.devicePixelRatio || 1) / backingStore
    },
    /* 将base64转换为文件对象
    * @param {String} base64 base64字符串
    * https://www.cnblogs.com/moqiutao/p/8657926.html
    * */
    convertBase64ToBlob (base64) {
      var base64Arr = base64.split(',')
      var imgtype = ''
      var base64String = ''
      if (base64Arr.length > 1) {
        // 如果是图片base64，去掉头信息
        base64String = base64Arr[1]
        imgtype = base64Arr[0].substring(base64Arr[0].indexOf(':') + 1, base64Arr[0].indexOf(';'))
      }
      // 将base64解码
      var bytes = atob(base64String)
      // var bytes = base64;
      var bytesCode = new ArrayBuffer(bytes.length)
      // 转换为类型化数组
      var byteArray = new Uint8Array(bytesCode)

      // 将base64转换为ascii码
      for (var i = 0; i < bytes.length; i++) {
        byteArray[i] = bytes.charCodeAt(i)
      }

      // 生成Blob对象（文件对象）
      return new Blob([bytesCode], { type: imgtype })
    },

    // 获取生成的图片文件
    getFile (fileName, content) {
      const aLink = document.createElement('a')
      const blob = this.convertBase64ToBlob(content) // new Blob([content]);

      const evt = document.createEvent('HTMLEvents')
      evt.initEvent('click', true, true)// initEvent 不加后两个参数在FF下会报错  事件类型，是否冒泡，是否阻止浏览器的默认行为
      aLink.download = fileName
      aLink.href = URL.createObjectURL(blob)

      aLink.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }))// 兼容火狐
    },

    print2PNGX_scale () {
      const mapCanvas = document.createElement('canvas')
      const size = this.$parent.imap.getSize()
      const width = size[0]
      const height = size[1]
      const mapContext = mapCanvas.getContext('2d')
      // context = canvas.getContext("2d"),
      const scale = this.getPixelRatio(mapContext) * 1
      mapCanvas.width = width * scale // 设置放大倍数,保证清晰度
      mapCanvas.height = height * scale // 设置放大倍数,保证清晰度
      mapCanvas.style.width = width + 'px'
      mapCanvas.style.height = height + 'px'
      mapContext.scale(scale, scale) // 设置放大倍数与上面的宽高对应

      html2canvas(document.body, { // document.getElementsByTagName("body")[0]
        tainttest: true, // 在渲染前测试图片(没整明白有啥用)
        useCORS: true, // 使用跨域(如果有跨域的话必须必须必须带着!)
        background: '#fff',
        scale: scale, // 添加的scale 参数
        canvas: mapCanvas, // 自定义 canvas
        logging: false, // 日志开关
        width: width, // dom 原始宽度
        height: height // dom 原始高度
      }).then(canvas => {
        // 图片导出为 png 格式
        var type = 'image/png'
        var imgData = canvas.toDataURL(type, 1)
        this.getFile('plot.png', imgData)
      })
    }
    // 当前方法
  }
}
</script>
